let obj = {
    name: 'jw'
}

function fn(name, age) {
    console.log(this)
    this.say = '说话'
    console.log(this.name, this.age)
}
// 1. bind 方法可以 绑定 this 指向
// 2. bind 方法返回一个 绑定后的 函数 (高阶函数)
// 3. 如果绑定的函数 被 new 了 当前函数的 this 就是当前实例
// 4. new 出来的结果可以找到原来的原型
Function.prototype.bind = function(ctx) {
    let that = this
    let bindArgs = Array.prototype.slice.call(arguments, 1)
    function Fn() {}
    function fBound() {
        let args = Array.prototype.slice.call(arguments)
        // that.call(ctx)
        return that.apply(this instanceof fBound ? this: context, bindArgs.concat(args))
    }
    // 通过 中间对象 桥接
    // 不直接公用 相同 prototype
    Fn.prototype = this.prototype
    fBound.prototype = new Fn()
    return fBound
}

fn.prototype.flag = '哺乳类'
let bindFn = fn.bind(obj, '猫')
// bindFn(9)
let instance = new bindFn(9) 
console.log(instance.flag, 'aaa')
